package com.elione.dao.base;

import java.io.Serializable;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.util.Assert;

import java.lang.reflect.Type;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;


/**
 * 
 * 
 * @author mhq
 * @version 1.0 (26.06.2015)
 * 
 * 
 */
public abstract class BaseDaoImpl<T,ID extends Serializable> implements BaseDao<T, ID> {

	private Logger logger = LogManager.getLogger( BaseDaoImpl.class );
	
	private Class<T> entityClass;
	
	@PersistenceContext
	protected EntityManager entityManager;
	
	@SuppressWarnings("unchecked")
	public BaseDaoImpl() {
		Type type = getClass().getGenericSuperclass();
		Type[] parameterizedType = ((ParameterizedType) type).getActualTypeArguments();
		entityClass = (Class<T>) parameterizedType[0];
	}
	
	public T find(ID id) {
		if (id != null) {
			return entityManager.find(entityClass, id);
		}
		return null;
	}
	
	public T persist(T entity) {
		Assert.notNull(entity);
		entityManager.persist(entity);
		return entity ;
	}
	
	public T merge(T entity) {
		Assert.notNull(entity);
		return entityManager.merge(entity);
	}
	
	/**
	 * 
	 * 在删除之前把这个Detached instance绑定到当前的Sesssion，在用当前Sesssion删除此instance
	 * EntityManager 提供merge方法实现。
	 */
	public void remove(T entity) {
		if (entity != null) {
			entityManager.remove( entityManager.merge( entity) );
		}
	}
	
	@SuppressWarnings("unchecked")
	public ID getIdentifier(T entity) {
		Assert.notNull(entity);
		return (ID) entityManager.getEntityManagerFactory().getPersistenceUnitUtil().getIdentifier(entity);
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<T> getEntityListByPage(int page, int rows) {
		int currentPage = ( page == 0 ? 1 : page ) ;
		int pageSize = ( rows == 0 ? 1 : rows ) ;
		
		int startIndex = ( currentPage - 1 ) * pageSize ;
		
		logger.debug(" StartIndex = " + startIndex + " , count =" + pageSize );
		Query query = entityManager.createQuery(" from " + entityClass.getSimpleName() );
		List<?> list = query.setFirstResult( startIndex ).setMaxResults( pageSize ).getResultList();
		List<T> result = new ArrayList<T>();
		for (Object object : list) {
			result.add( (T)object );
		}
		return result ;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<T> findAll() {
		Query query = entityManager.createQuery(" from " + entityClass.getSimpleName() );
		List<?> list = query.getResultList();
		List<T> result = new ArrayList<T>();
		if ( list != null && list.size() > 0 ) {
			for (Object object : list) {
				result.add( (T)object );
			}
		}
		return result ;
	}
	
	@Override
	public int getCount() {
		Query query = entityManager.createQuery("select count(*) from " + entityClass.getSimpleName() );
		List<?> result = query.getResultList();
		//这里显示的结果是long类型
		return Integer.valueOf( result.get(0).toString() );
	}
	
}
